#pragma once
namespace BFX
{

// Contains constants for specifying how the OS should open a file.
// These will control whether you overwrite a file, open an existing file, or some combination thereof.
enum FileMode
{
	// Creates a new file. An exception is raised if the file already exists.
	FileMode_CreateNew = 1,

	// Creates a new file. If the file already exists, it is overwritten.
	FileMode_Create = 2,

	// Opens an existing file. An exception is raised if the file does not exist.
	FileMode_Open = 3,

	// Opens the file if it exists. Otherwise, creates a new file.
	FileMode_OpenOrCreate = 4,

	// Opens an existing file. Once opened, the file is truncated so that its
	// size is zero bytes. The calling process must open the file with at least
	// WRITE access. An exception is raised if the file does not exist.
	FileMode_Truncate = 5,

	// Opens the file if it exists and seeks to the end.  Otherwise,
	// creates a new file.
	FileMode_Append = 6,
};

// Contains constants for specifying the access you want for a file.
// You can have Read, Write or ReadWrite access.
enum FileAccess
{
	// Specifies read access to the file. Data can be read from the file and
	// the file pointer can be moved. Combine with WRITE for read-write access.
	FileAccess_Read = 1,

	// Specifies write access to the file. Data can be written to the file and
	// the file pointer can be moved. Combine with READ for read-write access.
	FileAccess_Write = 2,

	// Specifies read and write access to the file. Data can be written to the
	// file and the file pointer can be moved. Data can also be read from the
	// file.
	FileAccess_ReadWrite = 3,
};

// Provides the fields that represent reference points for seeking
enum SeekOrigin
{
	// Specifies the beginning position.
	SeekOrigin_Begin = 0,
	// Specifies the current position.
	SeekOrigin_Current = 1,
	// Specifies the end position.
	SeekOrigin_End = 2,
};

// Represents a unbuffered file object.
class REFFile : public REFObject
{
public:


public:
	//
	// Constructions
	//
	REFFile();
	REFFile(const String& strFileName, FileMode mode, FileAccess access);
	virtual ~REFFile();

	//
	// Operations
	//

	// Opens a file.
	bool Open(const String& strFileName, FileMode mode, FileAccess access);

	// Gets a value indicating whether the current stream supports reading.
	bool CanRead() const;
	// Gets a value indicating whether the current stream supports writing.
	bool CanWrite() const;
	// Gets a value indicating whether the current stream supports seeking.
	bool CanSeek() const;

	// Reads data into a buffer from the file.
	int Read(BYTE* pBuf, int nCount);
	// Writes data from a buffer to the file.
	void Write(const BYTE* pBuf, int nCount);

	// Repositions the pointer in a previously opened file.
	INT64 Seek(INT64 lOff, SeekOrigin origin = SeekOrigin_Begin);
	// Sets the value of the file pointer to the beginning of the file.
	void SeekToBegin();
	// Sets the value of the file pointer to the logical end of the file.
	INT64 SeekToEnd();

	// Obtains the current logical length of the file in bytes.
	INT64 GetLength() const;

	// Call this member function to retrieve the full path of a specified file.
	String GetFilePath() const;

	// Obtains the current value of the file pointer, which can be used in subsequent calls to Seek.
	INT64 GetPosition() const;

	// Call this function to change the length of the file.
	void SetLength(INT64 nNewLen);

	// Closes the file associated with this object and makes the file unavailable for reading or writing.
	void Close();

	//
	// Static operations
	//

	// This static function deletes the file specified by the path.
	static bool Remove(const String& strFileName);

	// This static function renames the specified file.
	static bool Rename(const String& strOldFileName, const String& strNewFileName);

	//
	// Overrides
	//
	virtual bool IsValid() const;

protected:
#ifdef	_WIN32
	HANDLE		m_hFile;
#else
	int			m_hFile;
#endif
	String		m_strFileName;	// Fully qualified file name.

	bool	m_bCanRead;
	bool	m_bCanWrite;
	bool	m_bCanSeek;
};

}	//	namespace BFX
